package com.ss;

import com.esotericsoftware.reflectasm.ConstructorAccess;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author Ss
 * @version V1.0
 * @description
 * @date 2019/5/9
 */


public class WrappedReflectasmCopier {

    private static Map<String, Map<String, Field>> destPropertyMap = new ConcurrentHashMap<>();
    private static Map<String, ConstructorAccess> constructorAccessCache = new ConcurrentHashMap<>();

    /**
     * 只针对属性名 不判断类型  忽略大小写
     * 完整判断 待修改
     * @param obj
     * @param clz
     * @param <T>
     * @return
     */
    public static <T> T transferObjectIgnoreCase(Object obj, Class clz){
        T result;
        ConstructorAccess<T> access = constructorAccessCache.get(clz.getName());
        if (access == null) {
             access = ConstructorAccess.get(clz);
            constructorAccessCache.put(clz.getName(), access);
            if (obj != null) {
                //获取目标类的属性集合
                Map<String, Field> objectObjectHashMap = new HashMap<>();
                for (Field curField : clz.getDeclaredFields()) {
                    objectObjectHashMap.put(curField.getName().toLowerCase(), curField);
                }
                destPropertyMap.put(clz.getName(), objectObjectHashMap);
            }
        }
        result = access.newInstance();
        Map<String, Field> targetProMap = destPropertyMap.get(clz.getName());

        for (Field curField : obj.getClass().getDeclaredFields()) {
            Field targetField = targetProMap.get(curField.getName().toLowerCase());
            if (targetField != null) {
                targetField.setAccessible(true);
                curField.setAccessible(true);
                try {
                    targetField.set(result, curField.get(obj));
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }

        return result;
    }


}
